package core;

import java.io.File;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;

public class ExcelManipulation {
	private String fileName;
	private int countForCloseBrace = 0;
	private StringBuffer codeBuff;
	private int firstColumn = -1;
	private int rows, currentRow;

	public ExcelManipulation(String fileName) {
		this.fileName = fileName;
		codeBuff = new StringBuffer();
	}

	public String getCode() {
		return codeBuff.toString();
	}

	public boolean processingExcelFile() throws Exception {
		File inputWorkBook = new File(fileName);
		Workbook workbook = null;
		try {
			workbook = Workbook.getWorkbook(inputWorkBook);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		if (workbook != null) {
			int lengthOfSheet = workbook.getNumberOfSheets();
			for (int i = 0; i < lengthOfSheet; ++i) {
				Sheet sheet = workbook.getSheet(i);
				rows = sheet.getRows();
				currentRow = 0;
				firstColumn = -1;

				if (sheet.getName().endsWith("ActionForm"))
					processActionFormViewLayer(sheet);
				if (sheet.getName().endsWith("Event")) {
					processEventViewLayer(sheet, sheet.getName());
				}
				if (sheet.getName().equalsIgnoreCase("ModelLayer"))
					processModelLayer(sheet);
			}
		}
		return false;
	}

	private void indentOneTime(String name) {
		countForCloseBrace = countForCloseBrace + 1;
		++firstColumn;
		codeBuff.append(name + " {");
	}

	private void decreaseIndentOneTime() {
		--countForCloseBrace;
		--firstColumn;
		codeBuff.append('}');
	}

	private void processActionFormViewLayer(Sheet sheet) {
		indentOneTime("ActionForm");
		int typeIndex = -1, nameIndex = -1, IOIndex = -1, descriptionIndex = -1, index = -1;
		int valueIndex = -1;
		boolean flag = false;
		codeBuff.append(sheet.getName().substring(0,
				sheet.getName().indexOf("ActionForm")) + ' ');

		while (currentRow < rows) {
			String cellContent = sheet.getCell(firstColumn, currentRow)
					.getContents();

			if (!"".equals(cellContent)) {
				if ("description form".equalsIgnoreCase(cellContent)) {
					codeBuff.append("/*"
							+ sheet.getCell(firstColumn + 1, currentRow)
									.getContents() + "*/" + ' ');
				}

				if ("bean name".equalsIgnoreCase(cellContent)) {
					codeBuff.append(sheet.getCell(firstColumn + 1, currentRow)
							.getContents() + ' ');

					break;
				}

			}
			++currentRow;
		}
		++currentRow;

		while (currentRow < rows) {
			String cellContent = sheet.getCell(firstColumn, currentRow)
					.getContents();

			if (!"".equals(cellContent)) {
				int lengthOfColumnInRow = sheet.getRow(currentRow).length;

				for (int i = firstColumn; i < lengthOfColumnInRow; ++i) {
					String currentCell = sheet.getCell(i, currentRow)
							.getContents();

					if ("index".equalsIgnoreCase(currentCell))
						index = i;
					if ("type".equalsIgnoreCase(currentCell))
						typeIndex = i;
					if ("name".equalsIgnoreCase(currentCell))
						nameIndex = i;
					if ("I/O".equalsIgnoreCase(currentCell))
						IOIndex = i;
					if ("description".equalsIgnoreCase(currentCell))
						descriptionIndex = i;
					if ("value".equalsIgnoreCase(currentCell))
						valueIndex = i;
				}

				if (index != -1 && typeIndex != -1 && nameIndex != -1
						&& IOIndex != -1 && descriptionIndex != -1
						&& valueIndex != -1)
					flag = true;
				else {
					typeIndex = -1;
					nameIndex = -1;
					IOIndex = -1;
					descriptionIndex = -1;
					index = -1;
				}
			}

			++currentRow;
			if (flag)
				break;
		}

		if (flag) {
			flag = false;
			String typeContent = "", indexContent = "", nameContent = "", IOContent = "";
			String descriptionContent = "", valueContent = "", tempOfNameContent = "";
			for (; currentRow < rows; ++currentRow) {
				nameContent = sheet.getCell(nameIndex, currentRow)
						.getContents();
				if (nameContent.startsWith("    ")
						&& nameContent.indexOf("nt") != -1) {
					nameContent = tempOfNameContent;
					if (!"".equals(sheet.getCell(index, currentRow)
							.getContents()))
						indexContent = sheet.getCell(index, currentRow)
								.getContents();

					if (!"".equals(sheet.getCell(descriptionIndex, currentRow)
							.getContents()))
						descriptionContent = sheet.getCell(descriptionIndex,
								currentRow).getContents();

					if (!"".equals(sheet.getCell(valueIndex, currentRow)
							.getContents()))
						valueContent = sheet.getCell(valueIndex, currentRow)
								.getContents();
				} else {
					if (flag)
						codeBuff.append('}');
					codeBuff.append(nameContent + "{ ");
					flag = true;
					typeContent = sheet.getCell(typeIndex, currentRow)
							.getContents();

					indexContent = sheet.getCell(index, currentRow)
							.getContents();

					IOContent = sheet.getCell(IOIndex, currentRow)
							.getContents();

					descriptionContent = sheet.getCell(descriptionIndex,
							currentRow).getContents();

					valueContent = sheet.getCell(valueIndex, currentRow)
							.getContents();
				}

				codeBuff.append(indexContent + "//*" + descriptionContent
						+ "*//" + IOContent + "//*" + valueContent + "*//"
						+ typeContent + ';');
				tempOfNameContent = nameContent;
			}
			if (flag)
				codeBuff.append('}');

		}

		decreaseIndentOneTime();
	}

	private void processEventViewLayer(Sheet sheet, String sheetName) {
		indentOneTime("Event");
		codeBuff.append(sheetName.substring(0, sheetName.indexOf("Event")) + ' ');

		boolean flag = false;

		while (currentRow < rows) {
			String cellContent = sheet.getCell(firstColumn, currentRow)
					.getContents();

			if ("Item requires".equals(cellContent)) {
				flag = true;
				break;
			}

			if (!"".equals(cellContent)) {
				codeBuff.append(cellContent + " ");
			}

			++currentRow;
		}

		++currentRow;
		if (flag) {
			for (; currentRow < rows; ++currentRow) {
				String cellContent = sheet.getCell(firstColumn, currentRow)
						.getContents();
				if (!"".equals(cellContent)) {
					++currentRow;
					indentOneTime(cellContent);

					for (; currentRow < rows; ++currentRow) {
						if (!"".equals(sheet.getCell(firstColumn - 1,
								currentRow).getContents())) {
							--currentRow;
							break;
						}

						String keyCheckContent = sheet.getCell(firstColumn,
								currentRow).getContents();

						String typeCheckContent = sheet.getCell(
								firstColumn + 1, currentRow).getContents();

						String value1Content = sheet.getCell(firstColumn + 2,
								currentRow).getContents();

						String value2Content = sheet.getCell(firstColumn + 3,
								currentRow).getContents();

						codeBuff.append(keyCheckContent + "/check-"
								+ typeCheckContent + "/" + value1Content + '/'
								+ value2Content + ";");
					}
					decreaseIndentOneTime();
				}
			}

			// processFreeTextOutOfForm(sheet);
		}

		decreaseIndentOneTime();
	}

	private void processModelLayer(Sheet sheet) {
		indentOneTime(sheet.getName());
		int tableIndex = -1;

		while (currentRow < rows) {
			String cellContent = sheet.getCell(firstColumn, currentRow)
					.getContents();

			if (!"".equals(cellContent)) {
				if ("table name".equalsIgnoreCase(cellContent)) {
					tableIndex = firstColumn;
					break;
				}
			}

			++currentRow;
		}

		++currentRow;

		while (currentRow < rows)
			processWithTableInModelLayer(sheet, tableIndex);

		decreaseIndentOneTime();
	}

	private void processWithTableInModelLayer(Sheet sheet, int tableIndex) {
		int fieldNameIndex, typeIndex, lengthIndex, extraIndex;

		fieldNameIndex = tableIndex + 1;
		typeIndex = tableIndex + 2;
		lengthIndex = tableIndex + 3;
		extraIndex = tableIndex + 4;

		if (tableIndex != -1) {
			while (currentRow < rows) {
				String tableNameContent = sheet.getCell(tableIndex, currentRow)
						.getContents();

				++currentRow;
				if (!"".equals(tableNameContent)) {
					indentOneTime(tableNameContent);
					break;
				}
			}

			while (currentRow < rows
					&& "".equals(sheet.getCell(tableIndex, currentRow)
							.getContents())) {

				String fieldNameContent = sheet.getCell(fieldNameIndex,
						currentRow).getContents();

				if (!"".equals(fieldNameContent)) {
					String typeContent = sheet.getCell(typeIndex, currentRow)
							.getContents();
					String lengthContent = sheet.getCell(lengthIndex,
							currentRow).getContents();

					codeBuff.append(fieldNameContent + '/' + typeContent + '/'
							+ lengthContent);

					int lengthOfColumnInRow = sheet.getRow(currentRow).length;
					int tempExtraIndex = extraIndex;

					codeBuff.append('/');
					boolean isHave = true;

					while (tempExtraIndex < lengthOfColumnInRow) {
						String extraContent = sheet.getCell(tempExtraIndex,
								currentRow).getContents();

						if (!"".equals(extraContent)) {
							if (isHave) {
								codeBuff.deleteCharAt(codeBuff.length() - 1);
								isHave = false;
							}
							codeBuff.append('/' + extraContent);
						}
						++tempExtraIndex;
					}

					codeBuff.append(';');
				}
				++currentRow;
			}

			if (currentRow < rows) {
				while (currentRow < rows) {
					if ("Get".equals(sheet.getCell(tableIndex, currentRow)
							.getContents()))
						processWithSetGetInModelLayer(sheet, tableIndex, "get");
					else if ("Set".equals(sheet.getCell(tableIndex, currentRow)
							.getContents()))
						processWithSetGetInModelLayer(sheet, tableIndex, "set");
					else
						break;
				}
			}

			decreaseIndentOneTime();
		}
	}

	private void processWithSetGetInModelLayer(Sheet sheet, int tableIndex,
			String nameOfFunction) {
		int fieldNameIndex = -1, whereIndex = -1;

		++currentRow;
		codeBuff.append(nameOfFunction + " {");

		while (currentRow < rows) {
			String cellContent = sheet.getCell(firstColumn, currentRow)
					.getContents();

			if (!"".equals(cellContent)) {
				if ("Field Name".equalsIgnoreCase(cellContent)) {
					fieldNameIndex = firstColumn;
					whereIndex = fieldNameIndex + 1;
					break;
				}
			}

			++currentRow;
		}
		++currentRow;

		while (currentRow < rows
				&& "".equals(sheet.getCell(tableIndex, currentRow)
						.getContents())) {
			String fieldNameContent = sheet.getCell(fieldNameIndex, currentRow)
					.getContents();

			if (!"".equals(fieldNameContent)) {
				codeBuff.append(fieldNameContent);

				Cell[] cellsContent = sheet.getRow(currentRow);
				if (cellsContent.length > whereIndex) {
					for (int i = whereIndex; i < cellsContent.length; ++i) {
						String temp = sheet.getCell(i, currentRow)
								.getContents();
						if (!"".equals(temp))
							codeBuff.append("/" + temp);
					}
					codeBuff.append(';');
				} else
					codeBuff.append("/;");
			}
			++currentRow;
		}
		codeBuff.append('}');
	}
}